import _ from 'lodash';

import HistoryHelper from '../utils/HistoryHelper';
import SessionStorageProxy from '../utils/SessionStorageProxy';
import Console, { ConsoleUser, Region, ServiceStatus as ConsoleServiceStatus } from './Console';
import CtCas, { CasUser } from './CtCas';
import Config, { AppPublicConfig } from './Config';
import * as Enums from './Enums';

interface AppsSession {
  isOnline?: boolean,
  hasSubscribed?: boolean,
}

interface SessionContent extends AppPublicConfig, Record<Enums.ServiceTypes, AppsSession> {
  authUser?: CasUser,
  consoleUser?: ConsoleUser,
  consoleRegion?: Region,
}

// TODO: 合并 Session 与 ThirdPlatform Session
export default class Session {
  private static _content = new SessionStorageProxy<SessionContent>('ct-cns-main-app').getInstance();

  static init = async () => {
    await Session.refreshConfig();
  };

  static refreshConfig = async () => {
    const appConfig = await Config.fetchPublic();
    Object.assign(Session._content, appConfig);
  };

  static refreshMe = async () => {
    const url = new URL(window.location.href);
    const casTicket = url.searchParams.get('ticket');
    if (casTicket) {
      await CtCas.toValidateTicket(casTicket);
      url.searchParams.delete('ticket');
      HistoryHelper.replace(url.href);
    }
    const authUser = await CtCas.fetchMe();
    Session._content.authUser = authUser;
    const consoleUser = await Console.fetchMe();
    Session._content.consoleUser = consoleUser;
    const consolePermission = await Console.fetchPermission();
    Session._content.consoleRegion = consolePermission.platform;
    Session.updateAppsIsOnline(Session._content.consoleRegion);
  };

  static logout = async () => {
    const { redirectTo } = await CtCas.logout();
    Session._content = new SessionStorageProxy<SessionContent>('ct-cns-main-app').getInstance();
    HistoryHelper.replace(redirectTo);
  };

  static getAvailableSubApps = () => {
    return Session._content.availableSubApps;
  };

  static getOfApp = (service: Enums.ServiceTypes) => {
    return Session._content[service];
  };

  static updateOfApp = (service: Enums.ServiceTypes, params: Record<string, any>) => {
    const appSession = Session.getOfApp(service) || {};
    Session._content[service] = _.merge(appSession, params);
  };

  static hasSubscribedService = (service: Enums.ServiceTypes) => {
    return Session.getOfApp(service)?.hasSubscribed || false;
  };

  static setSubscribedService = (service: Enums.ServiceTypes, hasSubscribed: boolean) => {
    Session.updateOfApp(service, { hasSubscribed });
  };

  static getUserId = () => {
    return Session._content.authUser?.userid;
  };

  static getUsername = () => {
    return Session._content.consoleUser?.username;
  };

  static getAccountId = () => {
    return Session._content.authUser?.domainid;
  };

  static getCtUserId = () => {
    return Session._content.authUser?.domainid;
  };

  static getRegion = () => {
    return Session._content.consoleRegion;
  };

  static setRegion = async (region: Region) => {
    Session._content.consoleRegion = region;
    await Console.fetchPermission();
    HistoryHelper.reload();
  };

  static getRegionId = () => {
    return Session._content.consoleRegion?.zoneId;
  };

  static getRegionName = () => {
    return Session._content.consoleRegion?.zoneName;
  };

  private static updateAppsIsOnline = (region: Region) => {
    if (region.details?.security_safe === ConsoleServiceStatus.Enabled) {
      Session.updateOfApp(Enums.ServiceTypes.EShield, { isOnline: true });
    }
  };
}
